package com.itheima.health.Filter;

import com.alibaba.fastjson.JSON;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.Permission;
import com.itheima.health.pojo.Role;
import com.itheima.health.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
    String[] urls = new String[]{
            "/user/login",
            "/user/logout",
            "/mobile/**",
            "/common/**",

    };
    private Map<String, String> loginUrlMap = new HashMap<>();

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        initUrlMap();
    }

    private void initUrlMap() {
        loginUrlMap.put("/checkitem/findPage", "CHECKITEM_QUERY");     //查询检查项
        loginUrlMap.put("/checkitem/findById", "CHECKITEM_QUERY");     //查询检查项
        loginUrlMap.put("/checkitem/findAll", "CHECKITEM_QUERY");     //查询检查项
        loginUrlMap.put("/checkitem/add", "CHECKITEM_ADD");       //新增检查项
        loginUrlMap.put("/checkitem/delete", "CHECKITEM_DELETE");    //删除检查项
        loginUrlMap.put("/checkitem/edit", "CHECKITEM_EDIT");      //编辑检查项
        loginUrlMap.put("/checkgroup/findPage", "CHECKGROUP_QUERY");    //查询检查组
        loginUrlMap.put("/checkgroup/findAll", "CHECKGROUP_QUERY");    //查询检查组
        loginUrlMap.put("/checkgroup/findById", "CHECKGROUP_QUERY");    //查询检查组
        loginUrlMap.put("/checkgroup/query", "CHECKGROUP_QUERY");    //查询检查组
        loginUrlMap.put("/checkgroup/add", "CHECKGROUP_ADD");      //新增检查组
        loginUrlMap.put("/checkgroup/delete", "CHECKGROUP_DELETE");   //删除检查组
        loginUrlMap.put("/checkgroup/edit", "CHECKGROUP_EDIT");     //编辑检查组
        loginUrlMap.put("/setmeal/add", "SETMEAL_ADD");         //新增套餐
        loginUrlMap.put("/setmeal/delete", "SETMEAL_DELETE");      //删除套餐
        loginUrlMap.put("/setmeal/edit", "SETMEAL_EDIT");        //编辑套餐
        loginUrlMap.put("/setmeal/quert", "SETMEAL_QUERY");       //查询套餐
        loginUrlMap.put("/ordersetting", "ORDERSETTING");        //预约设置
        loginUrlMap.put("/report/view", "REPORT_VIEW");         //查看统计报表
        loginUrlMap.put("/menu/add", "MENU_ADD");            //新增菜单
        loginUrlMap.put("/menu/delete", "MENU_DELETE");         //删除菜单
        loginUrlMap.put("/menu/edit", "MENU_EDIT");           //编辑菜单
        loginUrlMap.put("/menu/query", "MENU_QUERY");          //查询菜单
        loginUrlMap.put("/role/add", "ROLE_ADD");            //新增角色
        loginUrlMap.put("/role/delete", "ROLE_DELETE");         //删除角色
        loginUrlMap.put("/role/edit", "ROLE_EDIT");           //编辑角色
        loginUrlMap.put("/role/query", "ROLE_QUERY");          //查询角色
        loginUrlMap.put("/user/add", "USER_ADD");            //新增用户
        loginUrlMap.put("/user/delete", "USER_DELETE");         //删除用户
        loginUrlMap.put("/user/edit", "USER_EDIT");           //编辑用户
        loginUrlMap.put("/user/query", "USER_QUERY");          //查询用户
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        // 获取URI
        String url = request.getRequestURI();
        log.info("[权限检查过滤器...],当前uri:{}", url);

        boolean check = check(url);

        if (check) {
            log.info("[权限检查过滤器],允许放行");
            chain.doFilter(request, response);
            return;
        }

//        User user = (User) request.getSession().getAttribute("user");
//        log.info("当前登录用户信息为：{}", user.getUsername());
//        Object member = request.getSession().getAttribute("member");
//        log.info("user:{}", user);

        if (request.getSession().getAttribute("user") != null) {
            User user = (User) request.getSession().getAttribute("user");

            log.info("[权限检查过滤器],已登录，检查当前用户是否需要授权访问，用户信息:{}", user.getUsername());

            Boolean isLogin = checkLoginUrl(url, user);
            if (isLogin) {
                chain.doFilter(request, response);
            } else {
                response.setContentType("application/json; charset=UTF-8");
                response.getWriter().write(JSON.toJSONString(new Result(false, "无操作权限")));
            }
        } else if (request.getSession().getAttribute("member") != null) {
            log.info("[权限检查过滤器],移动端用户登录，允许放行");
            chain.doFilter(request, response);
        } else {
            response.getWriter().write(JSON.toJSONString(new Result(false, "请重新登录")));
        }
    }

    /**
     * 判断是否放行当前URI请求
     *
     * @param requestURI
     * @return
     */
    private boolean check(String requestURI) {
        AntPathMatcher pathMatcher = new AntPathMatcher();

        for (String url : urls) {
            if (pathMatcher.match(url, requestURI)) {
                log.info("[权限检查过滤器],匹配放行的url:{}", url);
                return true;
            }
        }
        return false;
    }

    private Boolean checkLoginUrl(String url, User user) {
        AntPathMatcher pathMatcher = new AntPathMatcher();
        Set<String> keySets = loginUrlMap.keySet();
        String currKeyUrl = null;
        for (String urlKey : keySets) {
            if (pathMatcher.match(urlKey, url)) {
                currKeyUrl = urlKey;
            }
        }
        if (currKeyUrl == null) {
            log.info("[权限检查过滤器],当前用户访问的URI，无需权限，直接访问，reqUri：{}", url);
            return true;
        }
        String keyword = loginUrlMap.get(currKeyUrl);
        log.info("[权限检查过滤器],当前用户访问的uri需要授权，currKeyUrl:{},keyWord:{}", currKeyUrl, keyword);
        log.info("[权限检查过滤器],当前用户信息：user:{}", user);

        Set<Role> roles = user.getRoles();
        for (Role role : roles) {
            Set<Permission> permissions = role.getPermissions();
            for (Permission permission : permissions) {
                if (permission.getKeyword().equals(keyword)) {
                    log.info("[权限检查过滤器],当前用户匹配权限，允许方式，通过");
                    return true;
                }
            }
        }
        log.info("[权限检查过滤器],当前用户匹配权限不匹配，未通过");
        return false;
    }
}
